"""
提示词模板管理模块，集中管理所有LLM提示词
"""
import datetime
from typing import List, Dict, Any

def _get_current_time_context() -> Dict[str, Any]:
    """
    获取当前时间相关的上下文信息
    
    返回:
        包含各种时间格式和相关信息的字典
    """
    now = datetime.datetime.now()
    
    # 中英文星期对照
    weekday_cn = {
        0: "一",
        1: "二",
        2: "三",
        3: "四",
        4: "五", 
        5: "六",
        6: "日"
    }
    
    weekday_en = now.strftime("%A")
    weekday_cn_str = weekday_cn[now.weekday()]
    
    # 生成时间相关的上下文信息
    yesterday = now - datetime.timedelta(days=1)
    tomorrow = now + datetime.timedelta(days=1)
    last_week = now - datetime.timedelta(weeks=1)
    next_week = now + datetime.timedelta(weeks=1)
    
    # 计算本月开始和结束
    month_start = now.replace(day=1)
    if now.month == 12:
        next_month = now.replace(year=now.year+1, month=1, day=1)
    else:
        next_month = now.replace(month=now.month+1, day=1)
    month_end = next_month - datetime.timedelta(days=1)
    
    # 计算本季度信息
    current_quarter = (now.month - 1) // 3 + 1
    quarter_start_month = (current_quarter - 1) * 3 + 1
    quarter_start = now.replace(month=quarter_start_month, day=1)
    
    return {
        "now": now,
        "current_time": now.strftime("%Y年%m月%d日 %H:%M:%S"),
        "weekday_cn": weekday_cn,
        "weekday_en": weekday_en,
        "weekday_cn_str": weekday_cn_str,
        "yesterday": yesterday,
        "tomorrow": tomorrow,
        "last_week": last_week,
        "next_week": next_week,
        "month_start": month_start,
        "month_end": month_end,
        "current_quarter": current_quarter,
        "quarter_start": quarter_start,
    }

# 时间信息提示词模板
TIME_INFO_TEMPLATE = """
当前时间信息:
- 当前日期时间: {current_time}
- 今天是星期{weekday_cn_str} ({weekday_en})
- 昨天是: {yesterday} 星期{yesterday_weekday}
- 明天是: {tomorrow} 星期{tomorrow_weekday}
- 上周同一天: {last_week}
- 下周同一天: {next_week}
- 本月开始: {month_start}
- 本月结束: {month_end}
- 本季度: {year}年第{current_quarter}季度
- 本季度开始: {quarter_start}
- 当前年份: {year}
- 当前月份: {month}
- 当前日: {day}
- 当前小时: {hour}
- 当前分钟: {minute}
- 当前秒: {second}
- 当前时间戳(秒): {timestamp}
"""

# 时间推理指南提示词模板
TIME_REASONING_TEMPLATE = """
时间推理指南:
- 你应该独立分析用户查询中是否包含时间相关内容，无需依赖任何预定义规则或关键词列表
- 统一使用上述时间信息进行所有时间相关推理，不要使用训练数据中的过时信息
- 所有未明确指定日期的时间查询都默认使用今天（{today}）作为参考时间点
- 当用户使用"今天"、"现在"、"当前"等时间表达时，使用上面提供的具体日期和时间
- 当查询包含"明天"、"下周"、"下个月"等相对时间时，请以当前日期为基准进行计算
- 对于"本周"、"本月"、"本季度"等范围表述，使用上述相应的开始和结束日期
- 涉及具体时刻的查询(如"几点")，参考当前时间({hour}:{minute})并适当推理
- 在回答中避免使用"今天"、"明天"等相对表述，应提供精确日期("{today}")
- 对法定节假日、纪念日等时间节点的判断，必须基于当前日期进行推理，而非固定知识
- 时区相关内容应基于本地时间({current_time})，除非用户明确指定其他时区
- 即使查询看似与时间无关，也需要评估是否有隐含的时间依赖（如营业时间、活动日期等）
- 避免使用你训练数据中可能过时的时间信息，始终以上面提供的当前时间为准
"""

# 处理查询的系统提示词模板
SYSTEM_PROMPT_TEMPLATE = """你是一个智能助手，能够理解用户的需求并调用适当的工具帮助用户解决问题。
你将分析用户的问题，并根据需要自动调用最合适的工具。
{time_info}
{time_reasoning}
你可以访问以下工具:
{tools_info}

指导原则:
1. 直接调用相关工具，无需告知用户你要调用什么工具
2. 返回用户易于理解的答案，避免技术术语
3. 如果用户的问题与可用工具无关，直接回答，不要强行调用工具
4. 如果需要更多信息来满足用户请求，请礼貌地询问
5. 优先使用工具的返回结果回答用户，添加必要的解释使其更易理解
6. 如果需要使用多个工具解决复杂问题，可以按顺序调用多个工具
7. 工具之间的调用结果可以组合使用，你可以基于一个工具的结果去调用另一个工具
8. 某些复杂任务可能需要多轮工具调用，先获取信息再执行操作
9. 处理任务时要有整体规划，确保所有必要步骤都被执行
10. 所有涉及日期和时间的回答必须基于前面提供的当前时间信息，而非训练数据中的知识
11. 回答中提及日期时，尽量使用完整格式（例如"2023年5月1日"），而非"今天"、"明天"等相对表述
12. 主动识别查询中隐含的时间相关需求，并通过智能推理处理

请根据用户的问题，直接选择最合适的工具并调用。不要在回复中提及你正在使用工具，只需自然地回答用户问题即可。
"""

# 服务器选择提示词模板
SERVER_SELECTION_TEMPLATE = """你是一个智能路由系统，负责将用户查询分配给最合适的服务器。
根据用户的查询内容，你可以选择一个或多个服务器来协作完成任务。

{time_info}

时间推理说明:
- 通过分析用户查询内容智能识别时间相关需求，无需依赖任何预设关键词
- 识别查询是否与特定时间段或时间点相关，例如特定日期、季节、节假日等
- 评估时间因素对选择合适服务器的影响，如某些服务可能更适合处理特定时间段的查询
- 使用上述当前时间作为默认参考点，而不依赖训练数据中的知识

可用的服务器有:
{servers_info}

做出选择时，请遵循以下指导原则:
1. 如果一个服务器能够完全满足用户需求，只选择该服务器
2. 如果用户的查询需要多个服务器的协作才能完成，可以选择多个相关服务器
3. 选择的服务器应该是互补的，每个都能提供不同的功能或信息
4. 不要选择不相关的服务器，这会增加响应时间和系统负担
5. 最多选择3个服务器，优先选择最相关的服务器
6. 通过智能推理识别查询中的时间相关需求，不依赖预设规则或关键词
7. 对于时间敏感的查询，选择能提供最新或时间相关信息的服务器

你的回答应该只包含服务器ID，不要添加任何解释或理由。

请使用以下格式回答:
服务器ID: <服务器ID1>[,<服务器ID2>,<服务器ID3>]

单个服务器示例:
服务器ID: weather

多个服务器示例:
服务器ID: weather,news,calendar
"""

# 合并多服务器响应的提示词模板
MERGE_RESPONSES_TEMPLATE = """你是一个智能合并器，负责整合来自多个不同服务的回复，生成一个连贯、全面的回答。
请分析用户的原始查询和各个服务的回复，然后创建一个综合性的回答。

{time_info}

时间推理指南:
- 你应该独立分析原始查询中是否隐含时间相关内容，不依赖任何预设规则
- 所有时间相关推理统一使用上述时间信息，不依赖训练数据中的知识
- 对没有明确指定日期的时间查询，默认使用今天（{today}）作为参考点
- 回答中应尽量使用确切日期（如"{today}"）而非相对表述（如"今天"）
- 即使原始查询看似与时间无关，也应考虑是否有隐含的时间依赖
- 如某服务的回复提供了错误的时间信息，请以上述当前时间为准进行更正

合并原则:
1. 整合所有相关信息，避免重复
2. 优先保留实质性信息，确保结果准确性
3. 创建流畅自然的回答，不要提及"合并"或"服务器"等技术细节
4. 如果各服务提供互补信息，合理组织使其连贯
5. 如果服务之间有冲突信息，提供最可靠的信息或标明信息来源的不同
6. 使用与用户查询相同的语言回复
7. 如果原始查询是中文，则必须用中文回复
8. 如果原始查询是英文，则必须用英文回复
9. 保持回答的简洁性，但不要遗漏关键信息
10. 确保回答的格式统一，便于用户阅读
11. 对于时间相关回复，使用上述当前时间信息进行智能推理，而不是使用关键词匹配

请基于以下信息合成一个最佳回答:

用户原始查询: {original_query}

{server_responses}
"""

def get_system_prompt(tools: List) -> str:
    """
    获取处理用户查询的系统提示词
    
    参数:
        tools: 可用工具列表
        
    返回:
        完整的系统提示词
    """
    time_context = _get_current_time_context()
    now = time_context["now"]
    
    # 格式化时间信息
    time_info = TIME_INFO_TEMPLATE.format(
        current_time=time_context["current_time"],
        weekday_cn_str=time_context["weekday_cn_str"],
        weekday_en=time_context["weekday_en"],
        yesterday=time_context["yesterday"].strftime("%Y年%m月%d日"),
        yesterday_weekday=time_context["weekday_cn"][time_context["yesterday"].weekday()],
        tomorrow=time_context["tomorrow"].strftime("%Y年%m月%d日"),
        tomorrow_weekday=time_context["weekday_cn"][time_context["tomorrow"].weekday()],
        last_week=time_context["last_week"].strftime("%Y年%m月%d日"),
        next_week=time_context["next_week"].strftime("%Y年%m月%d日"),
        month_start=time_context["month_start"].strftime("%Y年%m月%d日"),
        month_end=time_context["month_end"].strftime("%Y年%m月%d日"),
        year=now.year,
        current_quarter=time_context["current_quarter"],
        quarter_start=time_context["quarter_start"].strftime("%Y年%m月%d日"),
        month=now.month,
        day=now.day,
        hour=now.hour,
        minute=now.minute,
        second=now.second,
        timestamp=int(now.timestamp())
    )
    
    # 格式化时间推理指南
    time_reasoning = TIME_REASONING_TEMPLATE.format(
        today=now.strftime("%Y年%m月%d日"),
        current_time=time_context["current_time"],
        hour=now.hour,
        minute=now.minute
    )
    
    # 格式化工具信息
    tools_info = "\n".join([f"- {tool.name}: {tool.description}" for tool in tools])
    
    # 生成完整提示词
    return SYSTEM_PROMPT_TEMPLATE.format(
        time_info=time_info,
        time_reasoning=time_reasoning,
        tools_info=tools_info
    )

def get_server_selection_prompt(servers_info: List[Dict[str, str]]) -> str:
    """
    获取服务器选择提示词
    
    参数:
        servers_info: 服务器信息列表
        
    返回:
        完整的服务器选择提示词
    """
    time_context = _get_current_time_context()
    now = time_context["now"]
    
    # 简化版时间信息
    time_info = f"""
当前时间信息:
- 日期时间: {time_context["current_time"]}
- 星期: {time_context["weekday_cn_str"]}
- 昨天: {time_context["yesterday"].strftime("%Y年%m月%d日")}
- 明天: {time_context["tomorrow"].strftime("%Y年%m月%d日")}
- 月初: {time_context["month_start"].strftime("%Y年%m月%d日")}
- 年份: {now.year} 
- 月份: {now.month}
- 日: {now.day}
- 季度: 第{time_context["current_quarter"]}季度
"""
    
    # 格式化服务器信息
    servers_text = "\n".join([f"- {server['id']}: {server['description']}" for server in servers_info])
    
    # 生成完整提示词
    return SERVER_SELECTION_TEMPLATE.format(
        time_info=time_info,
        servers_info=servers_text
    )

def get_merge_responses_prompt(original_query: str, server_messages: Dict[str, List[Dict[str, Any]]]) -> str:
    """
    获取合并多服务器响应的提示词
    
    参数:
        original_query: 原始查询
        server_messages: 各服务器的消息列表字典
        
    返回:
        完整的合并响应提示词
    """
    time_context = _get_current_time_context()
    now = time_context["now"]
    
    # 简化版时间信息
    time_info = f"""
当前时间信息: 
- 日期时间: {time_context["current_time"]}
- 星期: {time_context["weekday_cn_str"]}
- 昨天: {time_context["yesterday"].strftime("%Y年%m月%d日")} 星期{time_context["weekday_cn"][time_context["yesterday"].weekday()]}
- 明天: {time_context["tomorrow"].strftime("%Y年%m月%d日")} 星期{time_context["weekday_cn"][time_context["tomorrow"].weekday()]}
- 上周同一天: {time_context["last_week"].strftime("%Y年%m月%d日")}
- 下周同一天: {time_context["next_week"].strftime("%Y年%m月%d日")}
- 本月开始: {time_context["month_start"].strftime("%Y年%m月%d日")}
- 本月结束: {time_context["month_end"].strftime("%Y年%m月%d日")}
- 年份: {now.year}
- 月份: {now.month}
- 日: {now.day}
- 小时: {now.hour}
- 分钟: {now.minute}
- 当前季度: {time_context["current_quarter"]}
"""
    
    # 格式化服务器响应
    server_responses = ""
    for server_id, messages in server_messages.items():
        server_content = ""
        for msg in messages:
            if msg.get("role") == "assistant" and msg.get("content"):
                server_content += msg.get("content", "") + " "
        
        if server_content:
            server_responses += f"\n服务 {server_id} 的回复: {server_content.strip()}\n"
    
    # 生成完整提示词
    return MERGE_RESPONSES_TEMPLATE.format(
        time_info=time_info,
        today=now.strftime("%Y年%m月%d日"),
        original_query=original_query,
        server_responses=server_responses
    )

def get_merge_user_prompt() -> str:
    """
    获取合并响应时使用的用户提示词
    
    返回:
        用户提示词
    """
    return "请合并这些回复，创建一个最佳回答。如果原始查询是中文，请使用中文回答。对时间相关内容，请通过智能推理处理，不要依赖任何预设规则或关键词。" 